package com.apache.flow.taskHandler;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.jbpm.api.Execution;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.TaskService;
import org.jbpm.api.history.HistoryProcessInstanceQuery;
import org.jbpm.api.model.OpenExecution;
import org.jbpm.api.task.Assignable;
import org.jbpm.api.task.AssignmentHandler;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import org.jbpm.pvm.internal.task.TaskImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.SpringBeanAutowiringSupport;

import com.apache.common.DateUtil;
import com.apache.common.FlowClientUtil;
import com.apache.core.utils.web.struts2.Struts2Utils;
import com.apache.flow.core.entity.FlowAutomaticProcessing;
import com.apache.flow.core.entity.FlowHistroy;
import com.apache.flow.core.manager.FlowAutomaticProcessingManager;
import com.apache.flow.core.manager.FlowHistoryManager;
import com.apache.tools.PostHttp;
import com.apache.tools.StrUtil;

public class AssignTask extends SpringBeanAutowiringSupport implements AssignmentHandler {
	private Logger logger = LoggerFactory.getLogger(AssignTask.class);
	private static final long serialVersionUID = 1L;

	@Autowired
	private ProcessEngine processEngine;
	@Autowired
	private FlowAutomaticProcessingManager automaticProcessingManager;
	@Autowired
	private FlowHistoryManager flowHistoryManager;

	String action;//action路径
	String rightType;//权限类型
	//String rightValue;//权限值
	String taskType;//任务类型
	String taskExeType;//任务执行类型
	String keepDays;//保留天数
	String crossDept;//跨部门类型
	String userValue;//用户权限的用户集合
	String roleValue;//权限的用户集合

	@SuppressWarnings("unchecked")
	public void assign(Assignable assignable, OpenExecution execution) throws Exception {
		TaskService taskService = processEngine.getTaskService();
		FlowHistroy flowHistroy = new FlowHistroy();
		String pid = execution.getProcessInstance().getId();

		String activityName = execution.findActiveActivityNames().iterator().next();
		Task task = taskService.createTaskQuery().processInstanceId(pid).activityName(activityName).uniqueResult();
		logger.info("当前节点：【" + task.getName() + "】 获取信息：路径>" + action + "  权限类型>" + rightType + " 用户集合>" + userValue
				+ " 权限Id集合>" + roleValue + " 任务类型>" + taskType + " 任务执行类型>" + taskExeType + " 停留天数>" + keepDays
				+ " 是否跨部门>" + crossDept);
		String taskId = task.getId();
		flowHistroy.setHisTaskName(task.getName());
		logger.info("获取参数taskId=" + taskId);
		flowHistroy.setHisTaskId(taskId);
		flowHistroy.setHisCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));//创建时间
		flowHistroy.setHisProcessinsId(pid);//流程实例id
		flowHistroy.setHisState("0");//任务状态(为了后续更新预留字段)
		
		//标识：启动流程实例是否跳转到指定节点
		String startJumpFlag = (String)taskService.getVariable(taskId, "startJumpFlag");
		if(null != startJumpFlag && "true".equals(startJumpFlag)){
			return;
		}
		
		//保存流程变量信息
		Map<String, String> var = new HashMap<String, String>();
		if (taskType.equals(TaskType.AUTO)) {//自处理任务
			//向表中插入数据
			FlowAutomaticProcessing automaticProcessing = new FlowAutomaticProcessing();
			automaticProcessing.setTaskId(taskId);
			automaticProcessing.setCreateTime(DateUtil.getNowTime());
			automaticProcessing.setHandleStauts("0");
			automaticProcessing.setProcessInsId(pid);
			if (null != action && !"".equals(action)) {
				/*if (action.contains("?")) {
					automaticProcessing.setHandleUrl(action + "&taskId=" + taskId + "&processInsId=" + pid);
				} else {
					automaticProcessing.setHandleUrl(action + "?taskId=" + taskId + "&processInsId=" + pid);
				}*/
				String handleUrl = null;
				if (action.contains("?")) {
				    handleUrl = action + "&taskId=" + taskId + "&processInsId=" + pid;
				} else {
					handleUrl= action + "?taskId=" + taskId + "&processInsId=" + pid;
				}
				logger.info("开始执行自处理任务,调用URL地址为>"+handleUrl);
				PostHttp.postHttpString(handleUrl, null);
			} else {
				automaticProcessing.setHandleUrl("");
			}
			automaticProcessing.setHandleUrl(action == null ? "" : action + "?taskId=" + taskId + "&processInsId="
					+ pid);
			automaticProcessingManager.saveOrUpdateAutomaticProcessing(automaticProcessing);
			logger.info("添加自处理任务成功,taskId为>" + taskId + ",调用Action路径为>" + automaticProcessing.getHandleUrl());

			//flowHistroy.setHisAssignee(assignee);//任务提交人,此字段冻结不使用
			flowHistroy.setHisFormDay("");//保留天数
			flowHistroy.setHisFormId("");//表单id
			flowHistroy.setHisFormInfo("");//表单信息
			flowHistroy.setHisFormName("");//表单名称
			flowHistroy.setHisFormPrice("");//资金
			flowHistroy.setHisFormType("");//表单类型
			flowHistroy.setHisNextUser("自处理");//下一个审批人
			flowHistroy.setHisSysEname("");//系统名称
			flowHistroy.setHisUserName("");//任务提交人
		} else {
			String[] val = null;
			String nextUsers = StrUtil.doNull((String) taskService.getVariable(taskId, "nextUsers"), "");
			logger.info("指定下一审核人    nextUsers=" + nextUsers);
			Set<String> set = new HashSet<String>();
			if (null != nextUsers && !"".equals(nextUsers)) {//如果指定了下一审核人
				val = nextUsers.split(",");

				for (int i = 0; i < val.length; i++) {
					set.add(val[i]);
				}

			} else {//未指定下一审核人
				if (StrUtil.isNotNull(userValue)) {//如果用户集合值不为空
					val = userValue.split(",");

					for (int i = 0; i < val.length; i++) {
						set.add(val[i]);
					}
				}

				if (StrUtil.isNotNull(roleValue)) {//如果权限集合值不为空
					String deptId = (String) taskService.getVariable(taskId, "deptId");
					val = roleValue.split(",");
					for (int i = 0; i < val.length; i++) {
						String actId = val[i];
						if (StrUtil.isNotNull(actId)) {
							String users = FlowClientUtil.getUserStr(actId, crossDept, deptId);
							if (StrUtil.isNotNull(users)) {
								String[] users_str = users.split(",");

								for (int j = 0; j < users_str.length; j++) {
									if (StrUtil.isNotNull(users_str[j])) {
										set.add(users_str[j]);
									}
								}
							}

						}
					}

				}

				//	    			if(rightType.equals(RightType.USER)){//权限类型为用户
				//	    		        	val = rightValue.split(",");
				//	    		        	logger.info("权限类型为用户,用户长度为："+val.length+"  这些用户为："+rightValue);
				//    		        }else{//权限类型为权限
				//	        			String deptId=(String)taskService.getVariable(taskId, "deptId");
				//			        	String users=FlowClientUtil.getUserStr(rightValue, crossDept, deptId);
				//			        	if(users!=null&&!"".equals(users)){
				//			    			val=users.toString().split(",");
				//			    			logger.info("权限类型为权限,用户长度为："+val.length+"  这些用户为："+users);
				//			    		}else{
				//			    			logger.error("权限类型为权限,没有获取到用户");
				//			    			throw new org.jbpm.api.JbpmException("没有找到用户");
				//			    		}
				//    		        }
			}

			if (set.isEmpty()) {//如果用户集合为空
				throw new org.jbpm.api.JbpmException("没有找到用户");//没有没有找到审核人，则抛出异常
			}
			String lastUser = StrUtil.doNull((String) taskService.getVariable(taskId, "lastUser"), "");
			String userName = StrUtil.doNull((String) taskService.getVariable(taskId, "userName"), "");
			String formId = StrUtil.doNull((String) taskService.getVariable(taskId, "formId"), "");
			String formDay = StrUtil.doNull((String) taskService.getVariable(taskId, "formDay"), "");
			String formPrice = StrUtil.doNull((String) taskService.getVariable(taskId, "formPrice"), "");
			String formType = StrUtil.doNull((String) taskService.getVariable(taskId, "formType"), "");
			String formName = StrUtil.doNull((String) taskService.getVariable(taskId, "formName"), "");
			String formInfo = StrUtil.doNull((String) taskService.getVariable(taskId, "formInfo"), "");
			String sysEname = StrUtil.doNull((String) taskService.getVariable(taskId, "sysEname"), "");
			logger.info("流程变量参数：lastUser>" + lastUser + " userName>" + userName + " formId>" + formId + " formDay>"
					+ formDay + " formPrice>" + formPrice + " formType>" + formType + " formName>" + formName
					+ "  formInfo>" + formInfo + "  sysEname>" + sysEname);
			var.put("lastUser", lastUser);
			if (val != null && !"".equals(val)) {

				Iterator<String> iter = set.iterator();
				while (iter.hasNext()) {
					String assignee = iter.next();
					TaskImpl subTask = ((TaskImpl) task).createSubTask();
					subTask.setAssignee(assignee);
					subTask.setName(task.getName());
					subTask.setFormResourceName(action);

					String description = null;
					if (keepDays != null && !"".equals(keepDays)) {//判断停留天数
						Date laterDate = DateUtil.getTheBeforeXDate(task.getCreateTime(), Integer.valueOf(keepDays));
						description = String.valueOf(laterDate.getTime());
					} else {
						description = "";
					}
					description += TaskTag.splitTag + formId + TaskTag.splitTag + formName + TaskTag.splitTag
							+ formInfo + TaskTag.splitTag + formType + TaskTag.splitTag + lastUser + TaskTag.splitTag
							+ userName + TaskTag.splitTag + sysEname + TaskTag.splitTag + TaskTag.splitTag;
					subTask.setDescription(description);
					// 这句话是关键 只有设定同样的实例 子任务才能获得主任务设定的变量  
					subTask.setExecution((ExecutionImpl) execution);

					flowHistroy.setHisAssignee(assignee);//任务提交人,此字段冻结不使用
					flowHistroy.setHisFormDay(formDay);//保留天数
					flowHistroy.setHisFormId(formId);//表单id
					flowHistroy.setHisFormInfo(formInfo);//表单信息
					flowHistroy.setHisFormName(formName);//表单名称
					flowHistroy.setHisFormPrice(formPrice);//资金
					flowHistroy.setHisFormType(formType);//表单类型
					flowHistroy.setHisNextUser(assignee);//下一个审批人
					flowHistroy.setHisSysEname(sysEname);//系统名称
					flowHistroy.setHisUserName(userName);//任务提交人

					if (taskExeType.equals(TaskExeType.GRAB)) {
						taskService.addTaskParticipatingUser(task.getId(), assignee, Participation.CANDIDATE);
					} else {
						taskService.addTaskParticipatingUser(task.getId(), assignee, Participation.CLIENT);
					}
				}

				//	        		int cnt = val.length;
				//			        for(int i = 0; i < cnt; i++){
				//			        	TaskImpl subTask=((TaskImpl)task).createSubTask(); 
				//			            subTask.setAssignee(val[i]); 
				//			            subTask.setName(task.getName());  
				//			            subTask.setFormResourceName(action); 
				//			            
				//			            String description=null;
				//			            if(keepDays!=null&&!"".equals(keepDays)){//判断停留天数
				//							Date laterDate=DateUtil.getTheBeforeXDate(task.getCreateTime(),Integer.valueOf(keepDays));
				//			            	description=String.valueOf(laterDate.getTime());
				//			            }else{
				//			            	description="";
				//			            }
				//			            description+=TaskTag.splitTag+formId+TaskTag.splitTag+formName+TaskTag.splitTag+formInfo+TaskTag.splitTag+formType+TaskTag.splitTag+lastUser+TaskTag.splitTag+userName+TaskTag.splitTag;
				//			            subTask.setDescription(description);
				//			            // 这句话是关键 只有设定同样的实例 子任务才能获得主任务设定的变量  
				//			            subTask.setExecution((ExecutionImpl) execution); 
				//			            
				//		            	if(taskExeType.equals(TaskExeType.GRAB)){
				//		            		taskService.addTaskParticipatingUser(task.getId(), val[i], Participation.CANDIDATE);
				//		            	}else{
				//		            		taskService.addTaskParticipatingUser(task.getId(), val[i], Participation.CLIENT);
				//		            	}
				//			            
				//			            
				//			        }
			}

		}
		flowHistoryManager.save(flowHistroy);
		//保存流程变量信息
		//var.put("parentTaskId", taskId);
		var.put("action", action);
		var.put("rightType", rightType);
		//var.put("rightValue", rightValue);
		var.put("userValue", userValue);
		var.put("roleValue", roleValue);
		var.put("taskType", taskType);
		var.put("taskExeType", taskExeType);
		var.put("keepDays", keepDays);
		var.put("crossDept", crossDept);
		var.put("nextUsers", "");
		var.put("lastUser", "");

		logger.info("审核结束后,保存起来的流程变量参数");
		//logger.info("parentTaskId  "+taskId);
		logger.info("action  " + action);
		logger.info("rightType  " + rightType);
		logger.info("userValue  " + userValue);
		logger.info("roleValue  " + roleValue);
		logger.info("taskType  " + taskType);
		logger.info("taskExeType  " + taskExeType);
		logger.info("keepDays  " + keepDays);
		logger.info("crossDept  " + crossDept);
		logger.info("审核结束后,流程变量参数遍历结束");
		taskService.setVariables(taskId, var);
		if (taskType.equals(TaskType.AUTO)) {//自处理任务
			this.complete(taskId,"T");
		}
	}
	
	
	@SuppressWarnings("unused")
	public String complete(String taskId,String result ){
		logger.info("完成自处理节点：获取到taskId=" + taskId + "  result=" + result);
		String taskName = "";
		String returnResult="F";
		String instFlag="";
		String errmsg = "";
		if (null != taskId && !"".equals(taskId) && null != result && !"".equals(result)) {
			try {
				TaskService taskService = processEngine.getTaskService();
				Task task = taskService.getTask(taskId);
				taskName = task.getName();
				if (task != null) {

					String exeId = task.getExecutionId();
					ExecutionService executionService = processEngine.getExecutionService();
					Execution execution = executionService.findExecutionById(exeId);
					Execution processInstance = execution.getProcessInstance();
					String processInstanceId = processInstance.getId();
					Map<String, String> variables = new HashMap<String, String>();
					variables.put("taskId", taskId);
					variables.put("result", result);
					ZbxTask sign = new ZbxTask(task, variables);
					processEngine.execute(sign);

					HistoryService historyService = processEngine.getHistoryService();
					HistoryProcessInstanceQuery historyProcessInstanceQuery = historyService
							.createHistoryProcessInstanceQuery();
					if ("ended".equals(historyProcessInstanceQuery.processInstanceId(processInstanceId).list().get(0)
							.getState())) {
						instFlag = "T";//流程结束
					}
					returnResult = "T";
					errmsg = "流程审核成功";
				} else {
					returnResult = "F";
					errmsg = "没有找到任务Id为" + taskId + "的任务";
				}

			} catch (org.jbpm.api.JbpmException e) {
				//流程定义返回错误信息
				returnResult = "F";
				if (e.getMessage().contains("没有找到用户")) {
					errmsg = "下一任务节点没有执行用户";
					Struts2Utils.getRequest().setAttribute("info", "下个任务节点未找到任务执行者");
				} else if (e.getMessage().contains("suspended")) {
					errmsg = "该流程已挂起";
					Struts2Utils.getRequest().setAttribute("info", "该流程已挂起");
				} else {
					errmsg = "流程审核时发送未知异常";
				}
				e.printStackTrace();
			} catch (Exception e) {
				returnResult = "F";
				errmsg = "流程审核时发送未知异常";
				e.printStackTrace();
			}
		} else {
			returnResult = "F";
			errmsg = "参数taskId或result参数未传递";
		}
		
		return returnResult;
	}
	
}